package com.sanchunhui.psc.bluetooth.bt

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.os.Bundle
import android.view.View
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.eightbitlab.rxbus.Bus
import com.sanchunhui.psc.R
import com.sanchunhui.psc.event.BlueClickConnectEvent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job

class BtClientActivity : AppCompatActivity(){

    companion object{
        private val TAG =javaClass.simpleName
    }
    /**
     * UI
     */
    private var itemStateTv: TextView? = null
    private lateinit var logTv: TextView
    private lateinit var sendMsgEd:EditText

    /**
     * logic
     */
    private var blueBeans: MutableList<BluetoothDevice> = mutableListOf()
    private lateinit var blueDeviceListAdapter: BtDeviceListAdapter
    private lateinit var bluetooth: BluetoothAdapter
    private val stringBuilder = StringBuilder()
    private var connectThread: ConnectThread? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_bl_client)

        bluetooth = BluetoothAdapter.getDefaultAdapter()
        logTv = findViewById(R.id.tv_log)
        sendMsgEd = findViewById(R.id.send_edit)

        initRecyclerView()
        BtBlueImpl.init(this)
            .registerBroadcast()
            .foundDevices { dev ->

                if (dev !in blueBeans && dev.name != null) {
                    blueBeans.add(dev)
                    blueDeviceListAdapter.setData(blueBeans)
                    blueDeviceListAdapter.notifyItemInserted(blueBeans.size)
                }
            }
        initObserve()
    }

    /**
     * 初始化 recyclerview
     */
    private fun initRecyclerView() {
        val recyclerView: RecyclerView = findViewById(R.id.recycler)
        val manager = LinearLayoutManager(this)

        recyclerView.layoutManager = manager
        blueDeviceListAdapter =
            BtDeviceListAdapter(this)
        recyclerView.adapter = blueDeviceListAdapter

    }

    /*
        注册监听
     */
    private fun  initObserve() {
        Bus.observe<BlueClickConnectEvent>().subscribe {
            run {
                itemStateTv = this.findViewById(R.id.blue_item_status_tv)
                connectThread = ConnectThread(it.dev, readListener, writeListener)
                connectThread?.start()
            }
        }
    }

    /**
     * 扫描蓝牙
     */
    fun scan(view: View) {
        blueBeans.clear()
        blueDeviceListAdapter.notifyDataSetChanged()
        BtBlueImpl.foundDevices { bean ->
                if (bean !in blueBeans && bean.name != null) {
                    blueBeans.add(bean)
                    blueDeviceListAdapter.setData(blueBeans)
                }
            }
    }

    val job = Job()
    val coroutineScope = CoroutineScope(job)

    /**
     * 连接类
     */

    inner class ConnectThread(
        val device: BluetoothDevice, val readListener: HandleSocket.BluetoothListener?,
        val writeListener: HandleSocket.BaseBluetoothListener?
    ) : Thread() {
        var handleSocket: HandleSocket? = null
        private val socket: BluetoothSocket? by lazy {
            readListener?.onStart()
            //监听该 uuid
            device.createRfcommSocketToServiceRecord(BtBlueImpl.BLUE_UUID)
        }

        override fun run() {
            super.run()
            //下取消
            bluetooth.cancelDiscovery()
            try {

                socket.run {
                    //阻塞等待
                    this?.connect()
                    //连接成功，拿到服务端设备名
                    socket?.remoteDevice?.let { readListener?.onConnected(it.name) }

                    //处理 socket 读写
                    handleSocket =
                        HandleSocket(this)
                    handleSocket?.start(readListener, writeListener)

                }
            } catch (e: Exception) {
                readListener?.onFail(e.message.toString())
            }
        }

        fun cancel() {
            socket?.close()
            handleSocket?.cancel()
        }
    }


    fun sendMsg(view: View) {
        connectThread?.handleSocket?.sendMsg(sendMsgEd.text.toString())
        sendMsgEd.setText("")

    }

    override fun onDestroy() {
        super.onDestroy()
        connectThread?.cancel()
        BtBlueImpl.release()
    }

    val readListener = object : HandleSocket.BluetoothListener {
        override fun onStart() {
            runOnUiThread {
                itemStateTv?.text = "正在连接..."
            }
        }

        override fun onReceiveData(socket: BluetoothSocket?,msg: String) {
            runOnUiThread {
                logTv.text = stringBuilder.run {
                    append(socket?.remoteDevice?.name+": "+msg).append("\n")
                    toString()
                }
            }
        }

        override fun onConnected(msg: String) {
            super.onConnected(msg)
            runOnUiThread {
                itemStateTv?.text = "已连接"
            }
        }

        override fun onFail(error: String) {
            runOnUiThread {
                logTv.text = stringBuilder.run {
                    append(error).append("\n")
                    toString()
                }
                itemStateTv?.text = "已配对"
            }
        }

    }
    val writeListener = object : HandleSocket.BaseBluetoothListener {

        override fun onsendMsg(socket: BluetoothSocket?, msg: String) {
            runOnUiThread {
                logTv.text = stringBuilder.run {
                    append("我: $msg").append("\n")
                    toString()
                }
            }
        }
        override fun onFail(error: String) {
           // Log.d(com.zhengsr.bluetoothdemo.TAG, "zsr write onFail: $error")
            logTv.text = stringBuilder.run {
                append("发送失败: $error").append("\n")
                toString()
            }
        }

    }

}